﻿using System;
using System.IO;
using Microsoft.VisualStudio.CommandBars;

namespace LazyPlugins.DeclarativeAddinCreator.Helpers
{
    public class AddinReflector
    {
        public static void LoadButtonsByConfiguration(ButtonLocationConfigurator configurator, AddinCreatorContext creatorContext)
        {
            VisitAndConfigureButtonsBasedOn(configurator.RootItem, creatorContext);
        }

        private static int buttonInsertLocation = 1;
        private static void VisitAndConfigureButtonsBasedOn(LocationConfigItem item, AddinCreatorContext creatorContext)
        {
            if (item is CommandBarConfigItem)
            {
                try
                {
                    creatorContext.Tag = creatorContext.Bars[item.Name];
                }
                catch
                {
                    //doesn't exist create it
                    creatorContext.Tag = creatorContext.ApplicationObject.Commands.AddCommandBar(item.Name, EnvDTE.vsCommandBarType.vsCommandBarTypeToolbar, null, 0);
                    ((CommandBar)creatorContext.Tag).Visible = true;
                }
                buttonInsertLocation = 1;
            }

            if (item is MenuConfigItem)
            {
                var bar = (CommandBar)creatorContext.Tag;
                creatorContext.Tag = bar.Controls[item.Name];
                buttonInsertLocation = 1;
            }

            if (item is ButtonConfigItem)
            {
                LoadButtonForType((ButtonConfigItem)item, creatorContext, buttonInsertLocation++);
            }

            foreach (LocationConfigItem subitem in item.Subitems)
            {
                VisitAndConfigureButtonsBasedOn(subitem, creatorContext.Copy());
            }
        }


        private static void LoadButtonForType(ButtonConfigItem buttonDesc, AddinCreatorContext creatorContext, int location)
        {
            string
                //commandBarName = "",
                //menuName = "",
                iconName = "",
                caption = "",
                description = "";

            GetButtonPropertiesFromTypeAttributes(
                                buttonDesc.ButtonType,
                                ref caption,
                                ref description,
                                ref iconName);


            var menu = creatorContext.Tag as CommandBarPopup;
            CommandBar commandBar;
            if(menu == null)
                commandBar = creatorContext.Tag as CommandBar;
            else
                commandBar = menu.CommandBar;

            string iconFullPath = Path.Combine(AddinRegistry.GetIconsDirectory(), iconName);
            IconUtils.AddCommandActionWithicon(commandBar,
                                        buttonDesc.ButtonType.Name,
                                        caption,
                                        description,
                                        iconFullPath,
                                        buttonDesc.ButtonType,
                                        creatorContext,
                                        location,
                                        buttonDesc.Visuals);

        }

        private static void GetButtonPropertiesFromTypeAttributes(Type type, ref string buttonCaption, ref string commandDescription, ref string iconName)
        {
            var attrib2 = GetAttrib<AddinButtonCaptionAttribute>(type);
            {
                buttonCaption = attrib2.Caption;
                commandDescription = attrib2.Desc;
            }

            var attrib3 = GetAttrib<AddinButtonIconNameAttribute>(type);
            {
                iconName = attrib3.IconName;
            }
        }

        private static T GetAttrib<T>(Type type) where T : class
        {
            object[] attributes = type.GetCustomAttributes(typeof(T), true);
            if (attributes.Length == 0)
            {
                return default(T);
            }
            return attributes[0] as T;
        }
    }
}
